package cn.ucox.web.ms.util;

import org.springframework.cglib.beans.BeanMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Bean处理工具<br>
 * 提供对象属性复制
 *
 * @author chenw
 * @create 2017-02-09 18:00
 * @email javacspring@gmail.com
 */

public class BeanUtil {

    /**
     * 将对象装换为map
     *
     * @param bean
     * @return
     */
    public static <T> Map<String, Object> beanToMap(T bean) {

        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            Map<String, Object> map = new HashMap<>(beanMap.size());
            for (Object key : beanMap.keySet()) {
                map.put(String.valueOf(key), beanMap.get(key));
            }
            return map;
        }
        return null;
    }

    public static <T> Map<String, String> bean2Map(T bean) {
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            Map<String, String> map = new HashMap<>(beanMap.size());
            for (Object key : beanMap.keySet()) {
                map.put(String.valueOf(key), String.valueOf(beanMap.get(key)));
            }
            return map;
        }
        return null;
    }

    /**
     * 将map装换为javabean对象
     *
     * @param map
     * @param bean
     * @return
     */
    public static <T> T mapToBean(Map<String, Object> map, T bean) {
        BeanMap beanMap = BeanMap.create(bean);
        beanMap.putAll(map);
        return bean;
    }

    /**
     * 将map装换为javabean对象
     *
     * @param map
     * @param bean
     * @return
     */
    public static <T> T map2Bean(Map<String, String> map, T bean) {
        BeanMap beanMap = BeanMap.create(bean);
        beanMap.putAll(map);
        return bean;
    }

    /**
     * 将List<T>转换为List<Map<String, Object>>
     *
     * @param objList
     * @return
     */
    public static <T> List<Map<String, Object>> objectsToMaps(List<T> objList) {
        List<Map<String, Object>> list = new ArrayList<>();
        if (objList != null && objList.size() > 0) {
            Map<String, Object> map;
            T bean;
            for (T anObjList : objList) {
                bean = anObjList;
                map = beanToMap(bean);
                list.add(map);
            }
        }
        return list;
    }

    /**
     * 将List<Map<String,Object>>转换为List<T>
     *
     * @param maps
     * @param clazz
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public static <T> List<T> mapsToObjects(List<Map<String, Object>> maps, Class<T> clazz) throws InstantiationException, IllegalAccessException {
        List<T> list = new ArrayList<>();
        if (maps != null && maps.size() > 0) {
            Map<String, Object> map;
            T bean;
            for (Map<String, Object> map1 : maps) {
                map = map1;
                bean = clazz.newInstance();
                mapToBean(map, bean);
                list.add(bean);
            }
        }
        return list;
    }


//    /**
//     * 获取Bean null值属性
//     *
//     * @param source 目标对象
//     * @return 空属性集合
//     */
//    public static String[] getNullPropertyNames(Object source) {
//        final BeanWrapper src = new BeanWrapperImpl(source);
//        PropertyDescriptor[] pds = src.getPropertyDescriptors();
//
//        Set<String> emptyNames = new HashSet<>();
//        for (PropertyDescriptor pd : pds) {
//            Object srcValue = src.getPropertyValue(pd.getName());
//            if (srcValue == null) emptyNames.add(pd.getName());
//        }
//        String[] result = new String[emptyNames.size()];
//        return emptyNames.toArray(result);
//    }

//    /**
//     * Bean属性复制
//     *
//     * @param src    源对象
//     * @param target 目标对象
//     */
//    public static void copyPropertiesIgnoreNull(Object src, Object target) {
//        org.springframework.beans.BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
//    }
//
//    /**
//     * 对象转MAP
//     *
//     * @param object 源对象
//     */
//    public static Map<String, Object> object2Map(Object object) {
//        if (null == object)
//            throw new NullPointerException("源目标对象为空");
//        Map<String, Object> map = new HashMap<>();
//        BeanInfo beanInfo = null;
//        try {
//            beanInfo = Introspector.getBeanInfo(object.getClass());
//        } catch (IntrospectionException e) {
//            e.printStackTrace();
//        }
//        if (null == beanInfo)
//            return map;
//        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
//        for (PropertyDescriptor property : propertyDescriptors) {
//            String key = property.getName(); //获取属性名
//            if (key.compareToIgnoreCase("class") == 0) {
//                continue;
//            }
//            Method getter = property.getReadMethod();
//            Object value;
//            try {
//                value = getter != null ? getter.invoke(object) : null;//获取值
//                map.put(key, value);
//            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
//                e.printStackTrace();
//            }
//        }
//        return map;
//    }
//
//    public static <T> T map2Object(Map<Object, Object> map, Class<T> target) {
//        try {
//            BeanInfo beanInfo = Introspector.getBeanInfo(target);
//            T instance = target.newInstance();
//            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
//
//            for (PropertyDescriptor property : propertyDescriptors) {
//                String key = property.getName();
//                if (map.containsKey(key)) {
//                    Object value = map.get(key);
//                    // 得到property对应的setter方法
//                    Method setter = property.getWriteMethod();
//                    setter.invoke(instance, value);
//                }
//            }
//            return instance;
//        } catch (Exception e) {
//            throw new RuntimeException("map to object error", e);
//        }
//    }
}
